class Player extends AcGameObject{
    constructor(playground,x,y,radius,color,speed,character,username,photo){
        super();
        this.x=x;
        this.y=y;
        this.vx=0;
        this.vy=0;
        this.damagex = 0;
        this.damagey = 0;
        this.damage_speed = 0;
        this.friction = 0.9;
        this.playground=playground;
        this.ctx=this.playground.game_map.ctx;
        this.move_length=0;
        this.radius=radius;
        this.color=color;
        this.speed=speed;
        this.character= character;
        this.username = username;
        this.photo = photo;
        this.eps=0.01;
        this.fireballs = [];


        this.cur_skill=null;
        if(this.character!=="robot"){
            this.img = new Image();
            this.img.src = this.photo;
        }
        if(this.character === "me"){
            this.fireball_coldtime = 3;
            this.fireball_img = new Image();
            this.fireball_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_9340c86053-fireball.png";
            this.blink_coldtime = 6;
            this.blink_img  = new Image();
            this.blink_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_daccabdc53-blink.png";

        }
    }
    start(){
        this.playground.player_count++;
        this.playground.notice_board.write("已就绪 ： "+ this.playground.player_count+"人");
        if(this.playground.player_count >= 3){
            this.playground.state = "fighting";
            this.playground.notice_board.write("Fightings");
        }



        if(this.character === "me"){
            this.add_listening_events();
        }else if(this.character === "robot"){
            this.ai_move_to();
        }
    }
    add_listening_events(){
        let outer=this;

        this.playground.game_map.$canvas.on("contextmenu",function(){
            return false;
        });
        this.playground.game_map.$canvas.mousedown(function(e){
            if(outer.playground.state !== "fighting")
                return true;
        const rect = outer.ctx.canvas.getBoundingClientRect();
            if(e.which===3){
                let tx = (e.clientX-rect.left)/outer.playground.scale;
                let ty = (e.clientY-rect.top)/outer.playground.scale;
                outer.move_to(tx,ty);

                if(outer.playground.mode === "multi mode"){
                    outer.playground.mps.send_move_to(tx,ty);
                }
            }else if(e.which===1){
                let tx = (e.clientX-rect.left)/outer.playground.scale;
                let ty = (e.clientY-rect.top)/outer.playground.scale;
                if(outer.cur_skill==="fireball"){
                    let fireball = outer.shoot_fireball(tx,ty);
                    outer.fireball_coldtime = 3;
                    if(outer.playground.mode === "multi mode"){
                        outer.playground.mps.send_shoot_fireball(tx,ty,fireball.uuid);
                    }
                }else if(outer.cur_skill === "blink"){
                    outer.blink(tx,ty);
                    outer.blink_coldtime = 6;
                    outer.move_length = 0;
                    if (outer.playground.mode === "multi mode"){
                        outer.playground.mps.send_blink(tx,ty);
                    }
                }
                outer.cur_skill = null;
            }
        })
        this.playground.game_map.$canvas.keydown(function(e){
            if (e.which  === 13){
                if(outer.playground.mode === "multi mode"){
                    outer.playground.chat_field.show_input();
                    return true;
                }
            }
            if(outer.playground.state !== "fighting")return true;
            if(outer.radius<outer.eps) return true;
            if(e.which===81){//q
                if (outer.fireball_coldtime > outer.eps)
                return true;
            
                outer.cur_skill="fireball";
                return false;
            }else if(e.which === 70){ //f
                if (outer.blink_coldtime > outer.eps)
                return true;
            
                outer.cur_skill = "blink";
                return false;
            }
        })
    }
    ai_move_to(){
        let tx = Math.random() * this.playground.width / this.playground.scale;
        let ty = Math.random() * this.playground.height / this.playground.scale;
        this.move_to(tx,ty);
    }
    move_to(tx,ty){
        this.move_length = this.get_dist(this.x,this.y,tx,ty);
        let angle=Math.atan2(ty-this.y,tx-this.x);
        this.vx=Math.cos(angle);
        this.vy=Math.sin(angle);
    }
    get_dist(x1,y1,x2,y2){
        let dx = x1-x2;
        let dy = y1-y2;
        return Math.sqrt(dx*dx+dy*dy);
    }
    shoot_fireball(tx,ty){
        let x = this.x;
        let y = this.y;
        let radius = 0.01;
        let angle = Math.atan2( ty - this.y, tx - this.x);
        let vx = Math.cos(angle), vy  = Math.sin(angle);
        let color = "orange";
        let speed =  0.5;
        let move_length = 1.5;
        let fireball = new FireBall(this.playground, this, x ,y ,radius, vx, vy, color, speed, move_length);
        this.fireballs.push(fireball);
        return fireball;
    }
    blink(tx,ty){
        let d = this.get_dist(this.x, this.y, tx, ty);
        d = Math.min(d,0.3);
        let angle = Math.atan2(ty - this.y, tx - this.x);
        this.x += d * Math.cos(angle);
        this.y += d * Math.sin(angle);

    }
    destory_fireball(uuid){
        for (let i=0;i<this.fireballs.length;i++){
            let fireball = this.fireballs[i];
            if(fireball.uuid === uuid){
                fireball.destory();
                break;
            }
        }
    }
    receive_attack(x, y,angle,damage,ball_uuid,attacker){
        attacker.destory_fireball(ball_uuid);
        this.x=x,this.y=y;
        this.is_attacked(angle, damage);
    }
    update(){
        this.update_move();
        if(this.character === "me" && this.playground.state === "fighting"){
            this.update_coldtime();
        }
        this.render();
    }
    update_coldtime(){
        this.fireball_coldtime -= this.timedelta/1000;
        this.fireball_coldtime = Math.max(this.fireball_coldtime,0);
        this.blink_coldtime -= this.timedelta/1000;
        this.blink_coldtime = Math.max(this.blink_coldtime,0);
    }
    update_move(){//更新玩家移动
         if(this.character === "robot"&&Math.random() < 1 / 180){
            let player = this.playground.players[0];
            this.shoot_fireball(player.x,player.y);

        }
        if(this.damage_speed>this.edp){
            this.vx = this.vy = 0;
            this.move_length = 0;
            this.x += this.damage_x * this.damage_speed * this.timedelta / 1000;
            this.y += this.damage_y * this.damage_speed * this.timedelta / 1000;
            this.damage_speed *= this.friction;
        }
        else if(this.move_length<this.eps)
        {
            this.move_length=0;
            this.vx=this.vy=0;
            if(this.character === "robot"){
                this.ai_move_to();
            }
        }else{
            let moved=Math.min(this.speed*this.timedelta/1000,this.move_length);
            this.x+=this.vx*moved;
            this.y+=this.vy*moved;
            this.move_length-=moved;
        }
       
    }
    is_attacked(angle,damage){
        this.radius -= damage;
        this.damage_x=Math.cos(angle);
        this.damage_y=Math.sin(angle);
        this.damage_speed = damage*100;
        this.speed*=1.25;
        for(let i = 0; i < 10 + Math.random() * 5; i ++ ){
            let x = this.x;
            let y = this.y;
            let radius = 1 + this.radius * (Math.random()) * 0.1;
            let angle = Math.PI * 2 * Math.random();
            let vx = Math.cos(angle),vy = Math.sin(angle);
            let color = this.color;
            let speed = this.speed * 10 * Math.random();
            new Particle(this.playground, x, y, radius, vx, vy, color, speed);
        }
        if(this.radius<this.eps){
            this.destory();

            return false;
        }
    }
    render(){
        let scale = this.playground.scale;

        if(this.character !== "robot"){
            this.ctx.save();
            this.ctx.beginPath();
            this.ctx.arc(this.x *scale, this.y * scale, this.radius*scale, 0, Math.PI * 2, false);
            this.ctx.stroke();
            this.ctx.clip();
            this.ctx.drawImage(this.img, (this.x - this.radius)*scale, (this.y - this.radius)*scale, this.radius * 2 * scale, this.radius * 2 * scale ); 
            this.ctx.restore();
        }else{
            this.ctx.beginPath();
            this.ctx.arc(this.x * scale,this.y * scale,this.radius*scale,0,Math.PI*2,false);
            this.ctx.fillStyle=this.color;
            this.ctx.fill();
        }
        if (this.character === "me" && this.playground.state === "fighting"){
            this.render_skill_coldtime();
        }
    }

    render_skill_coldtime(){
        let x = 1.5,y = 0.9,r = 0.04;
        let scale = this.playground.scale;
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.arc(x *scale, y * scale, r * scale, 0, Math.PI * 2, false);
        this.ctx.stroke();
        this.ctx.clip();
        this.ctx.drawImage(this.fireball_img, (x - r )*scale, (y - r)*scale, r * 2 * scale, r * 2 * scale ); 
        this.ctx.restore();

        if(this.fireball_coldtime > 0){
        //渲染冷却时间
        this.ctx.beginPath();
        this.ctx.moveTo(x * scale, y *scale);
        this.ctx.arc(x * scale,y * scale,r * scale,0-Math.PI/2,Math.PI*2 * (1 - this.fireball_coldtime/3)-Math.PI/2,true);
        this.ctx.lineTo(x*scale,y*scale);
        this.ctx.fillStyle="rgba(0,0,255,0.6)";
        this.ctx.fill();

        }

        x =1.62;
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.arc(x *scale, y * scale, r * scale, 0, Math.PI * 2, false);
        this.ctx.stroke();
        this.ctx.clip();
        this.ctx.drawImage(this.blink_img, (x - r )*scale, (y - r)*scale, r * 2 * scale, r * 2 * scale ); 
        this.ctx.restore();

        if(this.blink_coldtime > 0){
        //渲染冷却时间
        this.ctx.beginPath();
        this.ctx.moveTo(x * scale, y *scale);
        this.ctx.arc(x * scale,y * scale,r * scale,0-Math.PI/2,Math.PI*2 * (1 - this.blink_coldtime/6)-Math.PI/2,true);
        this.ctx.lineTo(x*scale,y*scale);
        this.ctx.fillStyle="rgba(0,0,255,0.6)";
        this.ctx.fill();

        }
    }

    on_destory(){
        if(this.character === "me"){
        this.playground.state = "over";
        }
        for(let i = 0 ;i < this.playground.players.length; i++){
            if(this.playground.players[i] === this){
                this.playground.players.splice(i,1);
                break;
            }
        }
    }
}
